package org

import (
    "os"
	"fmt"
	"strings"
	"errors"
	"io/ioutil"
	//"gopkg.in/yaml.v2"
	"dhfshop/models"
	//"dhfshop/models/consts"
	//"github.com/astaxie/beego"
	"github.com/astaxie/beego/orm"
	"github.com/bitly/go-simplejson"
)

// 全部资源列表
type Resource struct {
    ResourceId int64  `orm:"column(resource_id);pk;auto" json:"resource_id"`
	Menu       string `orm:"column(menu)" json:"menu" form:"menu"`                    //菜单
	Module     string `orm:"column(module)" json:"module" form:"module"`              //模块
	Name       string `orm:"column(name)" json:"name" form:"name"`                    // 资源名称
	Identity   string `orm:"column(identity);size(128);unique" json:"identity" form:"identity"` // 资源的唯一标识
	Action     string `orm:"size(32);column(action)" json:"action" form:"action"`     //操作（增加、删除、修改、查询等）
}

func init() {
	orm.RegisterModel(new(Resource))
}

var MapResourceVersion map[string]string

//初始化系统资源
func InitAllResource(resFileName string) (err error) {
	file, err := os.Open(resFileName)
	if err != nil {
		return err
	}
	defer file.Close()
	content, err := ioutil.ReadAll(file)
	if err != nil {
		return err
	}
	js, err := simplejson.NewJson(content)
	if err!=nil {
		return err
	}
	items, err := js.Get("resources").Array()
	if err!=nil {
		return err
	}
	resources := []*Resource{}
	MapResourceVersion = make(map[string]string)
	for i := 0; i < len(items); i++ {
		menu, _:= js.Get("resources").GetIndex(i).Get("menu").String()
		name, _:= js.Get("resources").GetIndex(i).Get("name").String()
		identity, _:= js.Get("resources").GetIndex(i).Get("identity").String()
		action, _:= js.Get("resources").GetIndex(i).Get("action").String()
		pRes := &Resource{Menu:menu,Name:name,Identity:identity,Action:action}
		resources = append(resources, pRes)
		MapResourceVersion[identity] = menu
	}
	srcCount := len(resources)
	dstCount, _:= GetResourcesCount()
	if srcCount > int(dstCount) {
	   err = ClearResources()
       err = AddMultiRess(resources)
	}
    return nil 
}

func AddMultiRess(list []*Resource) (err error) {
	size := len(list)
	o := models.GetDefaultDB()
	if size > 1 {
	    _, err = o.InsertMulti(size, list) 
	}else{
	   _, err = o.Insert(list[0])
	}
	return
}

func GetResourceById(id int64) (v *Resource, err error) {
	o := models.GetDefaultDB()
	v = &Resource{ResourceId: id}
	if err = o.Read(v); err == nil {
		return v, nil
	}
	return nil, err
}

//查询系统资源列表
func GetAllResources(query map[string]string,fields []string,order_by map[string]string,offset int,limit int)([]*Resource, int64,error) {
	o := models.GetDefaultDB()
	qs := o.QueryTable(new(Resource))
	for k, v := range query {
		k = strings.Replace(k, ".", "__", -1)
		qs = qs.Filter(k, v)
	}
	cnt, err := qs.Count()
	var sortFields []string
	for k, v := range order_by {
		orderby := ""
		if v == "desc" {
			orderby = "-" + k
		} else if v == "asc" {
			orderby = k
		} else {
			return nil, 0, errors.New("Error: Invalid order. Must be either [asc|desc]")
		}
		sortFields = append(sortFields, orderby)
	}
	var lists []*Resource
	qs = qs.OrderBy(sortFields...)
	if _, err := qs.Limit(limit, offset).All(&lists, fields...); err == nil {
		return lists, cnt, nil
	}
	return nil, 0, err
}

func GetResourcesCount()(int64, error){
	o := models.GetDefaultDB()
	qs := o.QueryTable(new(Resource))
	cnt, err := qs.Count()
	return cnt, err
}

func ClearResources() (err error) {
	o := models.GetDefaultDB()
	//_, err = o.Raw("DROP TABLE IF EXISTS `resource`").Exec()
	if exist := o.QueryTable(new(Resource)).Filter("resource_id__gte",0).Exist(); exist {
	    _, err = o.QueryTable(new(Resource)).Filter("resource_id__gte", 0).Delete()
	}
	return
}

func GetResByOrderVersion(orderVersion string,offset,limit int) (resources []*Resource, err error) {
	sql := fmt.Sprintf(`select * from resource where find_in_set(%s, role_ids) limit %d,%d`,orderVersion,offset,limit)
	o := models.GetDefaultDB()					
	_, err = o.Raw(sql).QueryRows(&resources)
	return
}
